package com;

import javax.swing.*;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import java.io.*;
import java.util.List;
import javax.swing.table.*;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.concurrent.atomic.AtomicReference;

public class ExcelViewerApp extends JFrame {
    static {
        System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.NullLogger");
    }
    // 新增：标题字体设置控件
    private JSpinner titleFontSizeSpinner;
    private JCheckBox titleBoldCheckbox;
    private JComboBox<String> blankRowCombo;
    private JCheckBox fillBlankRowsCheckbox;
    private static final String DB_NAME = "PrintSettings.db";
    private static final String TABLE_NAME = "header_settings";
    // 在ExcelViewerApp类中添加新的配置存储结构
    private Map<String, Map<String, String>> savedSettingsMap = new HashMap<>();
    private JComboBox<String> excelFileCombo;
    private JRadioButton option1, option2;
    private JCheckBox useYearCheckbox, useRetentionCheckbox;
    private JTextField[] columnFields = new JTextField[10];
    private JSpinner[] widthSpinners = new JSpinner[10];
    private JTextField groupField;
    private JCheckBox serialCheckbox;
    private Map<String, String> savedColumnSettings = new HashMap<>();
    private Map<String, String> savedWidthSettings = new HashMap<>();
    private Map<String, String> savedHeaderLeftSettings = new HashMap<>();
    private Map<String, String> savedHeaderCenterSettings = new HashMap<>();
    private Map<String, String> savedHeaderRightSettings = new HashMap<>();
    private Map<String, String> savedFontSettings = new HashMap<>();
    private JTextField headerLeftField;
    private JTextField headerCenterField;
    private JTextField headerRightField;
    private JSpinner headerFontSizeSpinner;
    private JSpinner bodyFontSizeSpinner;
    private JCheckBox headerBoldCheckbox;
    private JCheckBox bodyBoldCheckbox;
    // 提升副标题控件为成员变量（原为局部变量）
    private JSpinner subtitleFontSizeSpinner;
    private JCheckBox subtitleBoldCheckbox;
    private JTextField serialNameField;
    private JSpinner serialWidthSpinner;
    public static void main(String[] args) {
        System.out.println("'''\n" +
                "                               |~~~~~~~|\n" +
                "                               |       |\n" +
                "                               |       |\n" +
                "                               |       |\n" +
                "                               |       |\n" +
                "                               |       |\n" +
                "    |~.\\\\\\_\\~~~~~~~~~~~~~~xx~~~         ~~~~~~~~~~~~~~~~~~~~~/_//;~|\n" +
                "    |  \\  o \\_         ,XXXXX),                         _..-~ o /  |\n" +
                "    |    ~~\\  ~-.     XXXXX`)))),                 _.--~~   .-~~~   |\n" +
                "     ~~~~~~~`\\   ~\\~~~XXX' _/ ';))     |~~~~~~..-~     _.-~ ~~~~~~~\n" +
                "              `\\   ~~--`_\\~\\, ;;;\\)__.---.~~~      _.-~\n" +
                "                ~-.       `:;;/;; \\          _..-~~\n" +
                "                   ~-._      `''        /-~-~\n" +
                "                       `\\              /  /\n" +
                "                         |         ,   | |\n" +
                "                          |  '        /  |\n" +
                "                           \\/;          |\n" +
                "                            ;;          |\n" +
                "                            `;   .       |\n" +
                "                            |~~~-----.....|\n" +
                "                           | \\             \\\n" +
                "                          | /\\~~--...__    |\n" +
                "                          (|  `\\       __-\\|\n" +
                "                          ||    \\_   /~    |\n" +
                "                          |)     \\~-'      |\n" +
                "                           |      | \\      '\n" +
                "                           |      |  \\    :\n" +
                "                            \\     |  |    |\n" +
                "                             |    )  (    )\n" +
                "                              \\  /;  /\\  |\n" +
                "                              |    |/   |\n" +
                "                              |    |   |\n" +
                "                               \\  .'  ||\n" +
                "                               |  |  | |\n" +
                "                               (  | |  |\n" +
                "                               |   \\ \\ |\n" +
                "                               || o `.)|\n" +
                "                               |`\\\\) |\n" +
                "                               |       |\n" +
                "                               |       |\n" +
                "" +
                "孩子们,这不好笑" +
                "如有问题请加联系方式wx:c2070295150");
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception ignored) {}

        SwingUtilities.invokeLater(() -> {
            ExcelViewerApp app = new ExcelViewerApp();
            app.setVisible(true);
        });
    }




    public ExcelViewerApp() {
        super("鑫盾打印工具");
        setupDatabase();
        loadSavedSettings();
        createUI();
    }
    private void exportToWord(DefaultTableModel model, List<String> columns, List<Integer> widthRatios,
                              String filePath, String headerType) {
        System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.NullLogger");

        // 检查是否需要添加序号列
        boolean addSerialColumn = serialCheckbox.isSelected();
        if (addSerialColumn) {
            // 根据抬头类型设置序列列名
            String serialColName = "卷内文件目录".equals(headerType) ? "件号" : "序号";
            columns.add(0, serialColName);
            widthRatios.add(0, 5);
        }

        // 获取分组字段
        String groupColumn = groupField.getText().trim();
        boolean hasGrouping = !groupColumn.isEmpty();

        List<String> excelHeaders = new ArrayList<>();
        Map<Object, List<Vector<Object>>> groupedData = new LinkedHashMap<>();

        // 读取Excel数据并分组
        try (FileInputStream fis = new FileInputStream(filePath)) {
            Workbook workbook = filePath.endsWith(".xlsx") ?
                    new XSSFWorkbook(fis) : new HSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0);

            for (Cell cell : headerRow) {
                excelHeaders.add(getCellValueAsString(cell));
            }

            int groupColumnIndex = excelHeaders.indexOf(groupColumn);

            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Vector<Object> rowData = new Vector<>();
                for (int col = 0; col < excelHeaders.size(); col++) {
                    Cell cell = row.getCell(col);
                    rowData.add(cell != null ? getCellValueAsString(cell) : "");
                }

                Object groupKey = hasGrouping ?
                        (rowData.get(groupColumnIndex) != null ?
                                rowData.get(groupColumnIndex) : "未分组") : "所有数据";

                groupedData.computeIfAbsent(groupKey, k -> new ArrayList<>()).add(rowData);
            }
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this,
                    "读取Excel文件时出错: " + e.getMessage(),
                    "导出失败", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 让用户选择保存文件夹
        JFileChooser folderChooser = new JFileChooser();
        folderChooser.setDialogTitle("选择保存文件夹");
        folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

        if (folderChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
            return; // 用户取消
        }

        File outputFolder = folderChooser.getSelectedFile();
        if (!outputFolder.exists() && !outputFolder.mkdir()) {
            JOptionPane.showMessageDialog(this,
                    "无法创建输出文件夹: " + outputFolder.getAbsolutePath(),
                    "导出失败", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 为每个分组创建单独的Word文档
        int successCount = 0;
        int totalGroups = groupedData.size();

        // 修改：从界面输入框获取页眉列名
        String headerLeftCol = headerLeftField.getText().trim();
        String headerCenterCol = headerCenterField.getText().trim();
        String headerRightCol = headerRightField.getText().trim();

        for (Map.Entry<Object, List<Vector<Object>>> entry : groupedData.entrySet()) {
            Object groupKey = entry.getKey();
            List<Vector<Object>> groupRows = entry.getValue();

            // 创建文件名（清理非法字符）
            String safeGroupKey = groupKey.toString().replaceAll("[\\\\/:*?\"<>|]", "_");
            String fileName = headerType + "_" + safeGroupKey + ".docx";
            File outputFile = new File(outputFolder, fileName);

            try (XWPFDocument doc = new XWPFDocument()) {
                setupPageProperties(doc, headerType);

                // 从每组第一条数据中获取页眉值
                Vector<Object> firstRow = groupRows.get(0);
                String leftValue = getValueFromRow(headerLeftCol, excelHeaders, firstRow);
                String centerValue = getValueFromRow(headerCenterCol, excelHeaders, firstRow);
                String rightValue = getValueFromRow(headerRightCol, excelHeaders, firstRow);

                // 创建页眉策略
                XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(doc);

                // 创建并初始化页眉 - 添加了缺失的 firstRow 和 policy 参数
                createHeaderContent(policy, leftValue, centerValue, rightValue,
                        headerType, groupKey.toString(),
                        headerLeftCol, headerCenterCol, headerRightCol);


                // 创建表格（行数包括表头+数据行）
                XWPFTable table = doc.createTable(groupRows.size() + 1, columns.size());

                // 设置表格样式（添加addSerialColumn参数）
                setupTableStyle(table, columns, widthRatios, excelHeaders, groupRows, addSerialColumn);

                // 添加25个空白行
                addBlankRows(table, columns.size());

                // 保存文档
                try (FileOutputStream out = new FileOutputStream(outputFile)) {
                    doc.write(out);
                    successCount++;
                } catch (Exception e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(this,
                            "导出分组 " + groupKey + " 时出错: " + e.getMessage(),
                            "部分导出失败", JOptionPane.WARNING_MESSAGE);
                }
            } catch (Exception e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(this,
                        "创建分组 " + groupKey + " 文档时出错: " + e.getMessage(),
                        "部分导出失败", JOptionPane.WARNING_MESSAGE);
            }
        }

        // 显示导出结果
        if (successCount > 0) {
            JOptionPane.showMessageDialog(this,
                    "成功导出 " + successCount + "/" + totalGroups + " 个分组文档到:\n" +
                            outputFolder.getAbsolutePath(),
                    "导出完成", JOptionPane.INFORMATION_MESSAGE);
        } else {
            JOptionPane.showMessageDialog(this,
                    "没有成功导出任何分组文档",
                    "导出失败", JOptionPane.ERROR_MESSAGE);
        }
    }

    // 从行中获取指定列的值
    private String getValueFromRow(String columnName, List<String> headers, Vector<Object> row) {
        if (columnName == null || columnName.isEmpty()) return "";
        int index = headers.indexOf(columnName);
        if (index >= 0 && index < row.size()) {
            Object value = row.get(index);
            return value != null ? value.toString() : "";
        }
        return "";
    }
    private void addBlankRows(XWPFTable table, int columnsCount) {
        // 添加25个空白行
        for (int i = 0; i < 25; i++) {
            XWPFTableRow blankRow = table.createRow();
            for (int j = 0; j < columnsCount; j++) {
                XWPFTableCell cell = blankRow.getCell(j);
                // 设置单元格边框
                CTTc cttc = cell.getCTTc();
                CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
                tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                setCellBorders(tcPr.addNewTcBorders());

                // 设置单元格内容为空
                if (cell.getParagraphs().isEmpty()) {
                    XWPFParagraph para = cell.addParagraph();
                    para.setAlignment(ParagraphAlignment.CENTER);
                    XWPFRun run = para.createRun();
                    run.setFontSize(10);
                    run.setFontFamily("宋体");
                    run.setText("");
                }
            }
        }
    }
    private XWPFHeader createAndInitializeHeader(XWPFHeaderFooterPolicy policy,
                                                 String year, String retention,
                                                 String headerType, String groupKey) {
        try {
            // 创建新页眉
            XWPFHeader header = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

            // 清除现有内容
            header.getParagraphs().forEach(header::removeParagraph);
            header.getTables().forEach(header::removeTable);

            // 创建页眉标题行
            XWPFParagraph titlePara = header.createParagraph();
            titlePara.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun titleRun = titlePara.createRun();
            titleRun.setText(headerType);
            titleRun.setBold(true);
            titleRun.setFontSize(16);
            titleRun.setFontFamily("黑体");

            // 创建信息行（分组、年度、保管期限）
            XWPFParagraph infoPara = header.createParagraph();
            infoPara.setAlignment(ParagraphAlignment.CENTER);

            // 设置制表位
            CTPPr ppr = infoPara.getCTP().addNewPPr();
            CTTabs tabs = ppr.addNewTabs();
            CTTabStop leftTab = tabs.addNewTab();
            leftTab.setVal(STTabJc.LEFT);
            leftTab.setPos(BigInteger.valueOf(0));
            CTTabStop rightTab = tabs.addNewTab();
            rightTab.setVal(STTabJc.RIGHT);
            rightTab.setPos(BigInteger.valueOf(9000));

            // 添加年度信息（居中）
            XWPFRun yearRun = infoPara.createRun();
            yearRun.setText("年度: " + year);
            yearRun.setFontSize(12);
            yearRun.setFontFamily("宋体");
            yearRun.addTab();

            // 添加保管期限（右对齐）
            XWPFRun retentionRun = infoPara.createRun();
            retentionRun.setText("保管期限: " + retention);
            retentionRun.setFontSize(12);
            retentionRun.setFontFamily("宋体");

            return header;
        } catch (Exception e) {
            System.err.println("创建页眉时出错: " + e.getMessage());
            return null;
        }
    }

    private void createHeaderContent(
            XWPFHeaderFooterPolicy policy,
            String leftValue, String centerValue, String rightValue,
            String headerType, String groupKey,
            String headerLeftCol, String headerCenterCol, String headerRightCol
    ) {
        try {
            // 获取页眉列名（从界面输入框直接获取）


            // 创建新页眉
            XWPFHeader header = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
            header.getParagraphs().forEach(header::removeParagraph);
            header.getTables().forEach(header::removeTable);

            // 创建页眉标题行
            XWPFParagraph titlePara = header.createParagraph();
            titlePara.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun titleRun = titlePara.createRun();
            titleRun.setText(headerType);
            titleRun.setBold(true);
            titleRun.setFontSize(22);
            titleRun.setFontFamily("黑体");

            // 创建三列的信息行
            XWPFTable infoTable = header.createTable(1, 3);
            infoTable.setWidth("100%");
            infoTable.getCTTbl().getTblPr().unsetTblBorders();

            XWPFTableRow row = infoTable.getRow(0);
            XWPFTableCell leftCell = row.getCell(0);
            XWPFTableCell centerCell = row.getCell(1);
            XWPFTableCell rightCell = row.getCell(2);

            // 设置单元格宽度
            leftCell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(3333));
            centerCell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(3333));
            rightCell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(3334));

            // 清除单元格内容
            clearCellContent(leftCell);
            clearCellContent(centerCell);
            clearCellContent(rightCell);

            // 左单元格（左对齐） - 使用用户在界面上设置的列名
            if (!headerLeftCol.isEmpty() && leftValue != null && !leftValue.isEmpty()) {
                XWPFParagraph leftPara = leftCell.addParagraph();
                leftPara.setAlignment(ParagraphAlignment.LEFT);
                XWPFRun leftRun = leftPara.createRun();
                leftRun.setText(headerLeftCol + ": " + leftValue); // 使用用户输入的列名
                leftRun.setFontSize(12);
                leftRun.setFontFamily("宋体");
            }

            // 中间单元格（居中） - 使用用户在界面上设置的列名
            if (!headerCenterCol.isEmpty() && centerValue != null && !centerValue.isEmpty()) {
                XWPFParagraph centerPara = centerCell.addParagraph();
                centerPara.setAlignment(ParagraphAlignment.CENTER);
                XWPFRun centerRun = centerPara.createRun();
                centerRun.setText(headerCenterCol + ": " + centerValue); // 使用用户输入的列名
                centerRun.setFontSize(12);
                centerRun.setFontFamily("宋体");
            }

            // 右单元格（右对齐） - 使用用户在界面上设置的列名
            if (!headerRightCol.isEmpty() && rightValue != null && !rightValue.isEmpty()) {
                XWPFParagraph rightPara = rightCell.addParagraph();
                rightPara.setAlignment(ParagraphAlignment.RIGHT);
                XWPFRun rightRun = rightPara.createRun();
                rightRun.setText(headerRightCol + ": " + rightValue); // 使用用户输入的列名
                rightRun.setFontSize(12);
                rightRun.setFontFamily("宋体");
            }

        } catch (Exception e) {
            System.err.println("创建页眉内容时出错: " + e.getMessage());
        }
    }

    // 辅助方法：清空单元格内容
    private void clearCellContent(XWPFTableCell cell) {
        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
            cell.removeParagraph(i);
        }
    }
    /**
     * 设置表格样式并填充数据
     * @param table Word表格对象
     * @param columns 列名列表
     * @param widthRatios 列宽比例列表
     * @param excelHeaders Excel表头
     * @param groupRows 分组数据行
     */
    private void setupTableStyle(XWPFTable table, List<String> columns, List<Integer> widthRatios,
                                 List<String> excelHeaders, List<Vector<Object>> groupRows,
                                 boolean addSerialColumn) {
        // 1. 设置表格基本属性
        table.setTableAlignment(TableRowAlign.CENTER);
        table.setWidth("100%");

        // 2. 设置表格边框
        setupTableBorder(table);

        // 3. 设置单元格内边距
        setTableCellPadding(table, 50, 50, 50, 50);

        // 4. 计算总宽度比例
        double totalRatio = widthRatios.stream().mapToInt(Integer::intValue).sum();
        if (totalRatio == 0) totalRatio = 1;

        // 5. 创建表头行
        XWPFTableRow headerRow = table.getRow(0);

        // 6. 设置表格网格(列宽)
        CTTblGrid grid = table.getCTTbl().addNewTblGrid();

        // 先添加序号列宽（如果需要）
        if (addSerialColumn) {
            CTTblGridCol serialGridCol = grid.addNewGridCol();
            serialGridCol.setW(BigInteger.valueOf((long) (5 / totalRatio * 10000)));
        }

        for (Integer ratio : widthRatios) {
            CTTblGridCol gridCol = grid.addNewGridCol();
            gridCol.setW(BigInteger.valueOf((long) ((ratio / totalRatio) * 10000)));
        }

        // 7. 设置表头单元格 - 修正序号列位置问题
        int cellIndex = 0;

        // 先添加序号列表头
        if (addSerialColumn) {
            XWPFTableCell cell = headerRow.getCell(cellIndex);
            if (cell == null) {
                cell = headerRow.addNewTableCell();
            }

            // 清空原有内容
            for (int j = cell.getParagraphs().size() - 1; j >= 0; j--) {
                cell.removeParagraph(j);
            }

            // 创建新段落
            XWPFParagraph para = cell.addParagraph();
            para.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun run = para.createRun();
            run.setText("序号");
            run.setFontSize(10);
            run.setFontFamily("宋体");
            run.setBold(true);

            // 设置表头样式
            CTTc cttc = cell.getCTTc();
            CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();

            // 设置垂直居中
            tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
            cellIndex++;
        }

        // 添加其他表头
        for (String column : columns) {
            XWPFTableCell cell = headerRow.getCell(cellIndex);
            if (cell == null) {
                cell = headerRow.addNewTableCell();
            }

            // 清空原有内容
            for (int j = cell.getParagraphs().size() - 1; j >= 0; j--) {
                cell.removeParagraph(j);
            }

            // 创建新段落
            XWPFParagraph para = cell.addParagraph();
            para.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun run = para.createRun();
            run.setText(column);
            run.setFontSize(10);
            run.setFontFamily("宋体");
            run.setBold(true);

            // 设置表头样式
            CTTc cttc = cell.getCTTc();
            CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();

            // 设置垂直居中
            tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
            cellIndex++;
        }

        // 修复点：使用正确方式设置标题行 - 替换了 CTHdr 的用法
        if (table.getRows().size() > 0) {
            XWPFTableRow firstRow = table.getRow(0);
            CTTrPr trPr = firstRow.getCtRow().isSetTrPr() ?
                    firstRow.getCtRow().getTrPr() :
                    firstRow.getCtRow().addNewTrPr();

            // 设置行属性为表头行 - 替代 CTHdr 的方法
            trPr.addNewTblHeader();
        }

        // 8. 填充数据行
        for (int rowIdx = 0; rowIdx < groupRows.size(); rowIdx++) {
            XWPFTableRow tableRow = table.getRow(rowIdx + 1);
            if (tableRow == null) {
                tableRow = table.createRow();
            }

            // 防止行跨页
            CTTrPr trPr = tableRow.getCtRow().addNewTrPr();
            trPr.addNewCantSplit().setVal(true);

            Vector<Object> fullRowData = groupRows.get(rowIdx);
            int cellIdx = 0;

            // 如果添加序号列，先处理序号列
            if (addSerialColumn) {
                XWPFTableCell serialCell = tableRow.getCell(cellIdx);
                if (serialCell == null) {
                    serialCell = tableRow.addNewTableCell();
                }

                // 清空单元格内容
                for (int j = serialCell.getParagraphs().size() - 1; j >= 0; j--) {
                    serialCell.removeParagraph(j);
                }

                // 创建新段落
                XWPFParagraph para = serialCell.addParagraph();
                para.setAlignment(ParagraphAlignment.CENTER);
                XWPFRun run = para.createRun();
                run.setText(String.valueOf(rowIdx + 1));  // 序号从1开始
                run.setFontSize(10);
                run.setFontFamily("宋体");

                // 设置单元格样式
                CTTc cttc = serialCell.getCTTc();
                CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
                tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                setCellBorders(tcPr.addNewTcBorders());
                cellIdx++;
            }

            // 处理其他列
            for (String column : columns) {
                XWPFTableCell cell = tableRow.getCell(cellIdx);
                if (cell == null) {
                    cell = tableRow.addNewTableCell();
                }

                // 清空单元格原有内容
                for (int j = cell.getParagraphs().size() - 1; j >= 0; j--) {
                    cell.removeParagraph(j);
                }

                // 创建新段落
                XWPFParagraph para = cell.addParagraph();

                // 设置对齐方式
                if ("责任者".equals(column) || "日期".equals(column)) {
                    para.setAlignment(ParagraphAlignment.CENTER);
                } else {
                    para.setAlignment(ParagraphAlignment.LEFT);
                }

                // 获取单元格值
                XWPFRun run = para.createRun();
                int excelColIndex = excelHeaders.indexOf(column);
                Object value = (excelColIndex >= 0 && excelColIndex < fullRowData.size()) ?
                        fullRowData.get(excelColIndex) : "";
                run.setText(value != null ? value.toString() : "");
                run.setFontSize(10);
                run.setFontFamily("宋体");

                // 设置单元格样式
                CTTc cttc = cell.getCTTc();
                CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
                tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);

                // 设置单元格边框
                CTTcBorders borders = tcPr.isSetTcBorders() ? tcPr.getTcBorders() : tcPr.addNewTcBorders();
                setCellBorders(borders);
                cellIdx++;
            }
        }
    }

    private String getColumnValueForGroup(String columnName, List<String> headers, List<Vector<Object>> groupRows) {
        if (groupRows == null || groupRows.isEmpty()) {
            return "";
        }

        int colIndex = headers.indexOf(columnName);
        if (colIndex < 0) {
            if ("年度".equals(columnName)) {
                colIndex = headers.indexOf("年份");
            } else if ("保管期限".equals(columnName)) {
                colIndex = headers.indexOf("保管期");
            }
            if (colIndex < 0) return "";
        }

        Vector<Object> firstRow = groupRows.get(0);
        if (firstRow.size() > colIndex) {
            Object value = firstRow.get(colIndex);
            return value != null ? value.toString().trim() : "";
        }
        return "";
    }

    private void saveDocument(XWPFDocument doc, String headerType) throws Exception {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileNameExtensionFilter("Word文档", "docx"));
        fileChooser.setSelectedFile(new File("目录文档_" + (headerType != null ? headerType : "") + ".docx"));

        if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
            File outputFile = fileChooser.getSelectedFile();
            if (!outputFile.getName().toLowerCase().endsWith(".docx")) {
                outputFile = new File(outputFile.getAbsolutePath() + ".docx");
            }

            try (FileOutputStream out = new FileOutputStream(outputFile)) {
                doc.write(out);
                JOptionPane.showMessageDialog(this,
                        "Word文档导出成功!\n保存位置: " + outputFile.getAbsolutePath(),
                        "导出成功", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }
    private void openSettings() {

        JDialog settingsDialog = new JDialog(this, "打印设置", true);
        settingsDialog.setSize(700, 1000);
        settingsDialog.setLocationRelativeTo(this);

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));

        JPanel headerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        headerPanel.add(new JLabel("选择抬头类型:"));

        JComboBox<String> settingCombo = new JComboBox<>(new String[]{"卷内文件目录", "盒内文件目录"});
        settingCombo.setPreferredSize(new Dimension(150, 25));
        headerPanel.add(settingCombo);

        mainPanel.add(headerPanel, BorderLayout.NORTH);

        JPanel settingsPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 0, 5, 10);
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        settingsPanel.add(new JLabel("设置常用列名和宽度比例:"), gbc);
        gbc.gridwidth = 1;

        JTextField[] settingFields = new JTextField[10];
        JSpinner[] settingSpinners = new JSpinner[10];

        for (int i = 0; i < 10; i++) {
            gbc.gridx = 0;
            gbc.gridy = 1 + i;
            settingsPanel.add(new JLabel("列名 " + (i + 1) + ":"), gbc);

            gbc.gridx = 1;
            settingFields[i] = new JTextField("");
            settingFields[i].setHorizontalAlignment(JTextField.CENTER);
            settingFields[i].setPreferredSize(new Dimension(200, 25));
            settingsPanel.add(settingFields[i], gbc);

            gbc.gridx = 2;
            settingsPanel.add(new JLabel("宽度比例:"), gbc);

            gbc.gridx = 3;
            settingSpinners[i] = new JSpinner(new SpinnerNumberModel(0, 0, 300, 10));
            JComponent editor = settingSpinners[i].getEditor();
            if (editor instanceof JSpinner.DefaultEditor) {
                ((JSpinner.DefaultEditor) editor).getTextField().setColumns(4);
            }
            settingsPanel.add(settingSpinners[i], gbc);
        }

        // 页眉设置
        gbc.gridx = 0;
        gbc.gridy = 11;
        gbc.gridwidth = 2;
        settingsPanel.add(new JLabel("页眉设置:"), gbc);
        gbc.gridwidth = 1;

        gbc.gridy = 12;
        settingsPanel.add(new JLabel("左列名:"), gbc);
        gbc.gridx = 1;
        JTextField headerLeftField = new JTextField("");
        headerLeftField.setPreferredSize(new Dimension(200, 25));
        settingsPanel.add(headerLeftField, gbc);

        gbc.gridx = 2;
        settingsPanel.add(new JLabel("中列名:"), gbc);
        gbc.gridx = 3;
        JTextField headerCenterField = new JTextField("");
        headerCenterField.setPreferredSize(new Dimension(200, 25));
        settingsPanel.add(headerCenterField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 13;
        settingsPanel.add(new JLabel("右列名:"), gbc);
        gbc.gridx = 1;
        JTextField headerRightField = new JTextField("");
        headerRightField.setPreferredSize(new Dimension(200, 25));
        settingsPanel.add(headerRightField, gbc);

        // 字体设置
        gbc.gridx = 0;
        gbc.gridy = 14;
        gbc.gridwidth = 2;
        settingsPanel.add(new JLabel("字体设置:"), gbc);
        gbc.gridwidth = 1;

        gbc.gridy = 15;
        settingsPanel.add(new JLabel("表头字体大小:"), gbc);
        gbc.gridx = 1;
        JSpinner headerFontSizeSpinner = new JSpinner(new SpinnerNumberModel(10, 6, 24, 1));
        settingsPanel.add(headerFontSizeSpinner, gbc);

        gbc.gridx = 2;
        settingsPanel.add(new JLabel("是否加粗:"), gbc);
        gbc.gridx = 3;
        JCheckBox headerBoldCheckbox = new JCheckBox();
        settingsPanel.add(headerBoldCheckbox, gbc);

        gbc.gridx = 0;
        gbc.gridy = 16;
        settingsPanel.add(new JLabel("正文字体大小:"), gbc);
        gbc.gridx = 1;
        JSpinner bodyFontSizeSpinner = new JSpinner(new SpinnerNumberModel(9, 6, 24, 1));
        settingsPanel.add(bodyFontSizeSpinner, gbc);

        gbc.gridx = 2;
        settingsPanel.add(new JLabel("是否加粗:"), gbc);
        gbc.gridx = 3;
        JCheckBox bodyBoldCheckbox = new JCheckBox();
        settingsPanel.add(bodyBoldCheckbox, gbc);

        gbc.gridx = 0;
        gbc.gridy = 17;
        settingsPanel.add(new JLabel("标题字体大小:"), gbc);
        gbc.gridx = 1;
        JSpinner titleFontSizeSpinner = new JSpinner(new SpinnerNumberModel(16, 6, 24, 1));
        settingsPanel.add(titleFontSizeSpinner, gbc);

        gbc.gridx = 2;
        settingsPanel.add(new JLabel("是否加粗:"), gbc);
        gbc.gridx = 3;
        JCheckBox titleBoldCheckbox = new JCheckBox();
        settingsPanel.add(titleBoldCheckbox, gbc);
// 副标题字体设置（页眉中的左中右列名）
        gbc.gridx = 0;
        gbc.gridy = 18; // 在标题字体设置下方
        settingsPanel.add(new JLabel("副标题字体大小:"), gbc);
        gbc.gridx = 1;
        JSpinner subtitleFontSizeSpinner = new JSpinner(new SpinnerNumberModel(9, 6, 24, 1));
        settingsPanel.add(subtitleFontSizeSpinner, gbc);

        gbc.gridx = 2;
        settingsPanel.add(new JLabel("是否加粗:"), gbc);
        gbc.gridx = 3;
        JCheckBox subtitleBoldCheckbox = new JCheckBox();
        settingsPanel.add(subtitleBoldCheckbox, gbc);

        JScrollPane scrollPane = new JScrollPane(settingsPanel);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        mainPanel.add(scrollPane, BorderLayout.CENTER);

        // 类型切换监听器 - 加载独立配置
        settingCombo.addActionListener(e -> {
            String type = (String) settingCombo.getSelectedItem();
            Map<String, String> settings = savedSettingsMap.getOrDefault(type, new HashMap<>());

            // 加载副标题设置
            String subtitleFontSetting = settings.getOrDefault("subtitle_font_settings", "9,false");
            String[] subtitleParts = subtitleFontSetting.split(",");
            if (subtitleParts.length >= 2) {
                subtitleFontSizeSpinner.setValue(Integer.parseInt(subtitleParts[0]));
                subtitleBoldCheckbox.setSelected(Boolean.parseBoolean(subtitleParts[1]));
            } else {
                subtitleFontSizeSpinner.setValue(9);
                subtitleBoldCheckbox.setSelected(false);
            }
            // 加载页眉设置
            headerLeftField.setText(settings.getOrDefault("header_left", ""));
            headerCenterField.setText(settings.getOrDefault("header_center", ""));
            headerRightField.setText(settings.getOrDefault("header_right", ""));

            // 加载字体设置
            String fontSettings = settings.getOrDefault("font_settings", "10,true,9,false,16,true");
            String[] parts = fontSettings.split(",");
            if (parts.length >= 6) {
                headerFontSizeSpinner.setValue(Integer.parseInt(parts[0]));
                headerBoldCheckbox.setSelected(Boolean.parseBoolean(parts[1]));
                bodyFontSizeSpinner.setValue(Integer.parseInt(parts[2]));
                bodyBoldCheckbox.setSelected(Boolean.parseBoolean(parts[3]));
                titleFontSizeSpinner.setValue(Integer.parseInt(parts[4]));
                titleBoldCheckbox.setSelected(Boolean.parseBoolean(parts[5]));
            }
        });

        // 初始加载 - 重用现有方法
        loadSettingsToFields(settingFields, settingSpinners, (String) settingCombo.getSelectedItem());
        String initialType = (String) settingCombo.getSelectedItem();
        Map<String, String> initialSettings = savedSettingsMap.getOrDefault(initialType, new HashMap<>());

        // 新增：加载副标题设置
        AtomicReference<String> subtitleFontSetting = new AtomicReference<>(initialSettings.getOrDefault("subtitle_font_settings", "9,false"));
        String[] subtitleParts = subtitleFontSetting.get().split(",");
        if (subtitleParts.length >= 2) {
            subtitleFontSizeSpinner.setValue(Integer.parseInt(subtitleParts[0]));
            subtitleBoldCheckbox.setSelected(Boolean.parseBoolean(subtitleParts[1]));
        } else {
            subtitleFontSizeSpinner.setValue(9);
            subtitleBoldCheckbox.setSelected(false);
        }
        // 加载页眉和字体设置

        headerLeftField.setText(initialSettings.getOrDefault("header_left", ""));
        headerCenterField.setText(initialSettings.getOrDefault("header_center", ""));
        headerRightField.setText(initialSettings.getOrDefault("header_right", ""));

        String fontSettings = initialSettings.getOrDefault("font_settings", "10,true,9,false,16,true");
        String[] parts = fontSettings.split(",");
        if (parts.length >= 6) {
            headerFontSizeSpinner.setValue(Integer.parseInt(parts[0]));
            headerBoldCheckbox.setSelected(Boolean.parseBoolean(parts[1]));
            bodyFontSizeSpinner.setValue(Integer.parseInt(parts[2]));
            bodyBoldCheckbox.setSelected(Boolean.parseBoolean(parts[3]));
            titleFontSizeSpinner.setValue(Integer.parseInt(parts[4]));
            titleBoldCheckbox.setSelected(Boolean.parseBoolean(parts[5]));
        }


        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
        JButton saveBtn = new JButton("保存");
        JButton cancelBtn = new JButton("取消");

        saveBtn.addActionListener(e -> {
            String headerType = (String) settingCombo.getSelectedItem();

            StringBuilder columnNames = new StringBuilder();
            StringBuilder widthRatios = new StringBuilder();

            for (int i = 0; i < settingFields.length; i++) {
                String text = settingFields[i].getText().trim();
                if (!text.isEmpty()) {
                    if (columnNames.length() > 0) {
                        columnNames.append(",");
                        widthRatios.append(",");
                    }
                    columnNames.append(text);
                    widthRatios.append(settingSpinners[i].getValue());
                }
            }

            // 获取页眉设置
            String headerLeft = headerLeftField.getText().trim();
            String headerCenter = headerCenterField.getText().trim();
            String headerRight = headerRightField.getText().trim();

            // 获取字体设置
            String fontSettingStr = headerFontSizeSpinner.getValue() + "," +
                    headerBoldCheckbox.isSelected() + "," +
                    bodyFontSizeSpinner.getValue() + "," +
                    bodyBoldCheckbox.isSelected() + "," +
                    titleFontSizeSpinner.getValue() + "," +
                    titleBoldCheckbox.isSelected();

            // 获取副标题设置（新增）
            String subtitleFontSize = String.valueOf(subtitleFontSizeSpinner.getValue());
            String subtitleBold = String.valueOf(subtitleBoldCheckbox.isSelected());
             subtitleFontSetting.set(subtitleFontSize + "," + subtitleBold);

            if (columnNames.length() > 0) {
                // 将副标题设置传入保存方法
                saveColumnSettings(headerType, columnNames.toString(), widthRatios.toString(),
                        headerLeft, headerCenter, headerRight,
                        fontSettingStr,
                        subtitleFontSetting.get()); // 传递副标题设置
                settingsDialog.dispose();

                // 直接调用现有的loadColumnsFromSaved方法
                String currentHeader = getSelectedHeaderType();
                if (headerType.equals(currentHeader)) {
                    loadColumnsFromSaved(columnNames.toString(), widthRatios.toString());
                }

                JOptionPane.showMessageDialog(this, "设置保存成功!");
            } else {
                JOptionPane.showMessageDialog(settingsDialog, "至少需要设置一个列名", "提示", JOptionPane.WARNING_MESSAGE);
            }
        });

        cancelBtn.addActionListener(e -> settingsDialog.dispose());

        buttonPanel.add(saveBtn);
        buttonPanel.add(cancelBtn);
        mainPanel.add(buttonPanel, BorderLayout.SOUTH);

        settingsDialog.add(mainPanel);
        settingsDialog.setVisible(true);
    }

    private void setupDatabase() {
        try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + DB_NAME);
             Statement stmt = conn.createStatement()) {

            String createTableSql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
                    "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    "header_type TEXT NOT NULL UNIQUE, " +
                    "column_names TEXT, " +
                    "width_ratios TEXT, " +
                    "header_left TEXT, " +
                    "header_center TEXT, " +
                    "header_right TEXT, " +
                    "font_settings TEXT, " +
                    "subtitle_font_settings TEXT" +
                    "serial_name TEXT, " +         // 新增字段
                    "serial_width INTEGER" +
                    ")";
            stmt.executeUpdate(createTableSql);

            checkAndAddColumns(conn);

        } catch (SQLException e) {
            JOptionPane.showMessageDialog(this, "数据库初始化失败: " + e.getMessage());
        }
    }

    private void checkAndAddColumns(Connection conn) {
        try {
            String[] columns = {"column_names", "width_ratios", "header_left",
                    "header_center", "header_right", "font_settings", "subtitle_font_settings"}; // 新增字段
            DatabaseMetaData dbMeta = conn.getMetaData();

            for (String col : columns) {
                ResultSet rs = dbMeta.getColumns(null, null, TABLE_NAME, col);
                if (!rs.next()) {
                    try (Statement stmt = conn.createStatement()) {
                        stmt.executeUpdate("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + col + " TEXT");
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    private void loadSavedSettings() {
        savedSettingsMap.clear(); // 清空现有配置

        try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + DB_NAME);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM " + TABLE_NAME)) {

            while (rs.next()) {
                String headerType = rs.getString("header_type");
                Map<String, String> typeSettings = new HashMap<>();


                typeSettings.put("column_names", rs.getString("column_names"));
                typeSettings.put("width_ratios", rs.getString("width_ratios"));
                typeSettings.put("header_left", rs.getString("header_left"));
                typeSettings.put("header_center", rs.getString("header_center"));
                typeSettings.put("header_right", rs.getString("header_right"));
                typeSettings.put("font_settings", rs.getString("font_settings"));
                typeSettings.put("subtitle_font_settings", rs.getString("subtitle_font_settings"));
                savedSettingsMap.put(headerType, typeSettings);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this,
                    "加载保存的设置失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }


    private void createUI() {
        setSize(800, 900);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel mainPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;

        JLabel titleLabel = new JLabel("鑫盾打印工具", JLabel.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
        gbc.gridwidth = 2;
        mainPanel.add(titleLabel, gbc);

        gbc.gridy++;
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.addTab("目录打印", createDirectoryPrintPanel());
        tabbedPane.addTab("封面打印(预留)", new JLabel("预留功能", JLabel.CENTER));
        mainPanel.add(tabbedPane, gbc);

        gbc.gridy++;
        gbc.gridwidth = 1;
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
        JButton previewBtn = new JButton("打印预览");
        JButton settingsBtn = new JButton("设置");
        JButton closeBtn = new JButton("关闭");

        previewBtn.addActionListener(e -> previewPrint());
        settingsBtn.addActionListener(e -> openSettings());
        closeBtn.addActionListener(e -> System.exit(0));

        buttonPanel.add(previewBtn);
        buttonPanel.add(settingsBtn);
        buttonPanel.add(closeBtn);
        mainPanel.add(buttonPanel, gbc);

        add(mainPanel);
        SwingUtilities.invokeLater(() -> {
            option1.setSelected(true);
            headerSelectionChanged();  // 确保初始化时加载卷内文件目录的配置

            // 设置独立字体默认值
            headerFontSizeSpinner.setValue(10);
            headerBoldCheckbox.setSelected(true);
            bodyFontSizeSpinner.setValue(9);
            bodyBoldCheckbox.setSelected(false);
            titleFontSizeSpinner.setValue(16);
            titleBoldCheckbox.setSelected(true);
        });
    }


    private JPanel createDirectoryPrintPanel() {
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 10, 5,10);
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 文件选择
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(new JLabel("档案文件(Excel):"), gbc);

        gbc.gridx = 1;
        JPanel filePanel = new JPanel(new BorderLayout());
        excelFileCombo = new JComboBox<>();
        excelFileCombo.setPreferredSize(new Dimension(350, 25));
        excelFileCombo.addItem("选择文件...");
        filePanel.add(excelFileCombo, BorderLayout.CENTER);

        JButton browseBtn = new JButton("浏览");
        browseBtn.addActionListener(e -> browseExcelFile());
        filePanel.add(browseBtn, BorderLayout.EAST);
        panel.add(filePanel, gbc);

        // 打印抬头
        gbc.gridx = 0;
        gbc.gridy = 1;
        panel.add(new JLabel("打印抬头:"), gbc);

        gbc.gridx = 1;
        JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
        option1 = new JRadioButton("卷内文件目录");
        option2 = new JRadioButton("盒内文件目录");
        ButtonGroup group = new ButtonGroup();
        group.add(option1);
        group.add(option2);
        radioPanel.add(option1);
        radioPanel.add(option2);
        panel.add(radioPanel, gbc);

        // 改为页眉设置输入框
        gbc.gridx = 0;
        gbc.gridy = 2;
        panel.add(new JLabel("页眉设置:"), gbc);

        gbc.gridx = 1;
        JPanel headerPanel = new JPanel(new GridLayout(1, 3, 10, 0));

        // 左列名
        JPanel leftPanel = new JPanel(new BorderLayout());
        leftPanel.add(new JLabel("左列名:"), BorderLayout.WEST);
        headerLeftField = new JTextField();
        headerLeftField.setPreferredSize(new Dimension(100, 25));
        leftPanel.add(headerLeftField, BorderLayout.CENTER);
        headerPanel.add(leftPanel);

        // 中列名
        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.add(new JLabel("中列名:"), BorderLayout.WEST);
        headerCenterField = new JTextField();
        headerCenterField.setPreferredSize(new Dimension(100, 25));
        centerPanel.add(headerCenterField, BorderLayout.CENTER);
        headerPanel.add(centerPanel);

        // 右列名
        JPanel rightPanel = new JPanel(new BorderLayout());
        rightPanel.add(new JLabel("右列名:"), BorderLayout.WEST);
        headerRightField = new JTextField();
        headerRightField.setPreferredSize(new Dimension(100, 25));
        rightPanel.add(headerRightField, BorderLayout.CENTER);
        headerPanel.add(rightPanel);

        panel.add(headerPanel, gbc);

        // 新增：字体设置
        gbc.gridx = 0;
        gbc.gridy = 3;
        panel.add(new JLabel("字体设置:"), gbc);


        gbc.gridx = 0;
        gbc.gridy = 3;
        panel.add(new JLabel("字体设置:"), gbc);

        gbc.gridx = 1;
        JPanel fontPanel = new JPanel(new GridLayout(2, 4, 10, 5)); // 改为2行4列布局

        // 表头字体设置
        fontPanel.add(new JLabel("表头字体大小:"));
        headerFontSizeSpinner = new JSpinner(); // 不再设置固定值
        fontPanel.add(headerFontSizeSpinner);

        fontPanel.add(new JLabel("是否加粗:"));
        headerBoldCheckbox = new JCheckBox();
        fontPanel.add(headerBoldCheckbox);

        // 正文字体设置
        fontPanel.add(new JLabel("正文字体大小:"));
        bodyFontSizeSpinner = new JSpinner();
        fontPanel.add(bodyFontSizeSpinner);

        fontPanel.add(new JLabel("是否加粗:"));
        bodyBoldCheckbox = new JCheckBox();
        fontPanel.add(bodyBoldCheckbox);

        // 将整个字体面板添加到主面板
        panel.add(fontPanel, gbc);

        gbc.gridx = 0;
        gbc.gridy = 5;
        panel.add(new JLabel("打印列名:"), gbc);

        gbc.gridx = 1;
        JPanel columnTitlePanel = new JPanel(new BorderLayout());
        columnTitlePanel.add(new JLabel("(列名)"), BorderLayout.WEST);
        columnTitlePanel.add(new JLabel("(宽度比例)"), BorderLayout.EAST);
        panel.add(columnTitlePanel, gbc);

        // 新增：序号列设置（放在打印列名上方）
        gbc.gridx = 0;
        gbc.gridy = 4;
        panel.add(new JLabel("序号列设置:"), gbc);

        gbc.gridx = 1;
        JPanel serialPanel = new JPanel(new BorderLayout(5, 0));

        // 左侧：自然序号复选框
        JPanel serialCheckPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        serialCheckbox = new JCheckBox("自然序号");
        serialCheckbox.setSelected(true);
        serialCheckPanel.add(serialCheckbox);
        serialPanel.add(serialCheckPanel, BorderLayout.WEST);

        // 中间：列名输入框
        JPanel serialNamePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
        serialNamePanel.add(new JLabel("列名:"));
        serialNameField = new JTextField("序号");
        serialNameField.setHorizontalAlignment(JTextField.CENTER);
        serialNameField.setPreferredSize(new Dimension(200, 25)); // 与打印列名相同宽度
        serialNamePanel.add(serialNameField);
        serialPanel.add(serialNamePanel, BorderLayout.CENTER);

        // 右侧：宽度比例设置
        JPanel serialWidthPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
        serialWidthPanel.add(new JLabel("宽度比例:"));
        serialWidthSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 100, 1));
        JComponent spinnerEditor = serialWidthSpinner.getEditor();
        if (spinnerEditor instanceof JSpinner.DefaultEditor) {
            ((JSpinner.DefaultEditor) spinnerEditor).getTextField().setColumns(3);
        }
        serialWidthPanel.add(serialWidthSpinner);
        serialPanel.add(serialWidthPanel, BorderLayout.EAST);

        panel.add(serialPanel, gbc);

        // 列名和比例输入框（保持不变）
        for (int i = 0; i < 10; i++) {
            gbc.gridx = 0;
            gbc.gridy = 6 + i;  // 注意：从6开始，因为序号列设置占用了第4行
            panel.add(new JLabel("列名 " + (i + 1) + ":"), gbc);

            gbc.gridx = 1;
            JPanel columnPanel = new JPanel(new BorderLayout(5, 0));
            columnFields[i] = new JTextField("");
            columnFields[i].setHorizontalAlignment(JTextField.CENTER);
            columnFields[i].setPreferredSize(new Dimension(200, 25)); // 与序号列名相同宽度
            columnPanel.add(columnFields[i], BorderLayout.CENTER);

            widthSpinners[i] = new JSpinner(new SpinnerNumberModel(0, 0, 300, 10));
            JComponent editor = widthSpinners[i].getEditor();
            if (editor instanceof JSpinner.DefaultEditor) {
                ((JSpinner.DefaultEditor) editor).getTextField().setColumns(4);
            }
            columnPanel.add(widthSpinners[i], BorderLayout.EAST);

            panel.add(columnPanel, gbc);
        }

        // 移除之前的序号列设置位置（原位置在列名输入框下方）
        // 分组标识（保持不变）
        gbc.gridx = 0;
        gbc.gridy = 16;
        panel.add(new JLabel("分组标识:"), gbc);

        gbc.gridx = 1;
        groupField = new JTextField();
        groupField.setHorizontalAlignment(JTextField.CENTER);
        groupField.setPreferredSize(new Dimension(350, 25));
        JPanel groupPanel = new JPanel(new BorderLayout());
        groupPanel.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(Color.GRAY), "输入列名进行分组打印"));
        groupPanel.add(groupField, BorderLayout.CENTER);
        panel.add(groupPanel, gbc);

        // 空白行设置（保持不变）
        gbc.gridx = 0;
        gbc.gridy = 17;
        panel.add(new JLabel("空白行设置:"), gbc);

        gbc.gridx = 1;
        JPanel blankRowPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        fillBlankRowsCheckbox = new JCheckBox("填充空白行");
        blankRowCombo = new JComboBox<>(new String[]{"0.5", "1", "1.5", "2"});
        blankRowCombo.setEnabled(false);
        blankRowCombo.setPreferredSize(new Dimension(60, 25));

        fillBlankRowsCheckbox.addActionListener(e -> {
            blankRowCombo.setEnabled(fillBlankRowsCheckbox.isSelected());
        });

        blankRowPanel.add(fillBlankRowsCheckbox);
        blankRowPanel.add(new JLabel("行高倍数:"));
        blankRowPanel.add(blankRowCombo);
        panel.add(blankRowPanel, gbc);
        // 修复空指针异常问题
        // 延迟调用headerSelectionChanged直到UI完全构建
        SwingUtilities.invokeLater(() -> {
            option1.setSelected(true);
            headerSelectionChanged();
        });

        // 添加监听器
        ActionListener radioListener = e -> headerSelectionChanged();
        option1.addActionListener(radioListener);
        option2.addActionListener(radioListener);

        return panel;
    }
    private void browseExcelFile() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileNameExtensionFilter("Excel文件", "xls", "xlsx"));

        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            String filePath = file.getAbsolutePath();

            if (!isItemInCombo(excelFileCombo, filePath)) {
                if (excelFileCombo.getItemCount() == 1 &&
                        excelFileCombo.getItemAt(0).equals("选择文件...")) {
                    excelFileCombo.removeItemAt(0);
                }
                excelFileCombo.addItem(filePath);
            }
            excelFileCombo.setSelectedItem(filePath);
        }
    }

    private boolean isItemInCombo(JComboBox<String> combo, String item) {
        for (int i = 0; i < combo.getItemCount(); i++) {
            if (combo.getItemAt(i).equals(item)) {
                return true;
            }
        }
        return false;
    }

    private void headerSelectionChanged() {
        String key = getSelectedHeaderType();
        // 重置序号列为默认值
        serialNameField.setText("序号");
        serialWidthSpinner.setValue(5);
        if (key != null && savedSettingsMap.containsKey(key)) {
            Map<String, String> settings = savedSettingsMap.get(key);


            serialNameField.setText(settings.getOrDefault("serial_name", "序号"));
            serialWidthSpinner.setValue(
                    Integer.parseInt(settings.getOrDefault("serial_width", "5"))
            );

            // 加载列名和宽度比例 - 确保类型独立
            String columnNames = settings.get("column_names");
            String widthRatios = settings.get("width_ratios");
            loadColumnsFromSaved(columnNames, widthRatios);

            // 加载页眉设置 - 确保类型独立
            headerLeftField.setText(settings.getOrDefault("header_left", ""));
            headerCenterField.setText(settings.getOrDefault("header_center", ""));
            headerRightField.setText(settings.getOrDefault("header_right", ""));

            // 加载字体设置 - 确保类型独立
            String fontSettings = settings.getOrDefault("font_settings", "10,true,9,false,16,true");
            String[] parts = fontSettings.split(",");
            if (parts.length >= 6) {
                headerFontSizeSpinner.setValue(Integer.parseInt(parts[0]));
                headerBoldCheckbox.setSelected(Boolean.parseBoolean(parts[1]));
                bodyFontSizeSpinner.setValue(Integer.parseInt(parts[2]));
                bodyBoldCheckbox.setSelected(Boolean.parseBoolean(parts[3]));
                titleFontSizeSpinner.setValue(Integer.parseInt(parts[4]));
                titleBoldCheckbox.setSelected(Boolean.parseBoolean(parts[5]));
            }
        } else {
            // 重置为对应类型的默认值
            resetColumnFieldsToDefault();
            resetWidthSpinners();
            headerLeftField.setText("");
            headerCenterField.setText("");
            headerRightField.setText("");
            // 设置不同类型的默认字体
            if ("卷内文件目录".equals(key)) {
                headerFontSizeSpinner.setValue(10);
                headerBoldCheckbox.setSelected(true);
                bodyFontSizeSpinner.setValue(9);
                bodyBoldCheckbox.setSelected(false);
                titleFontSizeSpinner.setValue(16);
                titleBoldCheckbox.setSelected(true);
            } else if ("盒内文件目录".equals(key)) {
                headerFontSizeSpinner.setValue(12);
                headerBoldCheckbox.setSelected(true);
                bodyFontSizeSpinner.setValue(10);
                bodyBoldCheckbox.setSelected(false);
                titleFontSizeSpinner.setValue(18);
                titleBoldCheckbox.setSelected(true);
            }
        }
    }

    private void resetColumnFieldsToDefault() {
        for (int i = 0; i < columnFields.length; i++) {
            columnFields[i].setText("");
        }
    }

    private void resetWidthSpinners() {
        for (int i = 0; i < widthSpinners.length; i++) {
            widthSpinners[i].setValue(0);
        }
    }

    private void loadColumnsFromSaved(String columnNamesStr, String widthRatiosStr) {
        String[] names = columnNamesStr != null ? columnNamesStr.split(",") : new String[0];
        String[] ratios = widthRatiosStr != null ? widthRatiosStr.split(",") : new String[0];

        for (int i = 0; i < columnFields.length; i++) {
            if (i < names.length && !names[i].isEmpty()) {
                columnFields[i].setText(names[i].trim());
            } else {
                columnFields[i].setText("");
            }

            if (i < ratios.length && !ratios[i].isEmpty()) {
                try {
                    widthSpinners[i].setValue(Integer.parseInt(ratios[i]));
                } catch (NumberFormatException e) {
                    widthSpinners[i].setValue(0);
                }
            } else {
                widthSpinners[i].setValue(0);
            }
        }
    }

    private String getSelectedHeaderType() {
        if (option1.isSelected()) return "卷内文件目录";
        if (option2.isSelected()) return "盒内文件目录";
        return null;
    }

    private void previewPrint() {
        String selectedFile = (String) excelFileCombo.getSelectedItem();
        if (selectedFile == null || "选择文件...".equals(selectedFile)) {
            JOptionPane.showMessageDialog(this, "请先选择Excel文件", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        List<String> userColumns = new ArrayList<>();
        List<Integer> widthRatios = new ArrayList<>();

        for (int i = 0; i < columnFields.length; i++) {
            String text = columnFields[i].getText().trim();
            if (!text.isEmpty()) {
                userColumns.add(text);
                widthRatios.add((Integer) widthSpinners[i].getValue());
            }
        }

        if (userColumns.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请设置至少一个打印列名", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

// 获取页眉设置 - 直接使用成员变量
        String headerLeft = headerLeftField.getText().trim();
        String headerCenter = headerCenterField.getText().trim();
        String headerRight = headerRightField.getText().trim();


        // 查找页眉设置输入框
        for (Component comp : this.getContentPane().getComponents()) {
            if (comp instanceof JPanel) {
                JPanel panel = (JPanel) comp;
                for (Component subComp : panel.getComponents()) {
                    if (subComp instanceof JTextField) {
                        // 根据位置判断是哪个输入框
                        Point loc = subComp.getLocation();
                        if (loc.y > 100 && loc.y < 150) { // 粗略判断页眉设置区域
                            if (loc.x < 200) headerLeft = ((JTextField) subComp).getText();
                            else if (loc.x < 400) headerCenter = ((JTextField) subComp).getText();
                            else headerRight = ((JTextField) subComp).getText();
                        }
                    }
                }
            }
        }

//        // 保存当前页眉设置到数据库
//        String headerType = getSelectedHeaderType();
//        if (headerType != null) {
//            saveHeaderSettings(headerType, headerLeft, headerCenter, headerRight);
//        }

        try (FileInputStream fis = new FileInputStream(selectedFile)) {
            Workbook workbook = selectedFile.endsWith(".xlsx") ?
                    new XSSFWorkbook(fis) : new HSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0);
            List<String> excelHeaders = new ArrayList<>();

            for (Cell cell : headerRow) {
                excelHeaders.add(getCellValueAsString(cell));
            }

            DefaultTableModel tableModel = new DefaultTableModel();
            for (String colName : userColumns) {
                tableModel.addColumn(colName);
            }

            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Vector<Object> dataRow = new Vector<>();
                for (String userCol : userColumns) {
                    int colIndex = excelHeaders.indexOf(userCol);
                    Object cellValue = "";

                    if (colIndex >= 0) {
                        Cell cell = row.getCell(colIndex);
                        if (cell != null) {
                            cellValue = getCellValueAsString(cell);
                        }
                    }
                    dataRow.add(cellValue);
                }
                tableModel.addRow(dataRow);
            }

            showPreviewTable(tableModel, userColumns, widthRatios, headerLeft, headerCenter, headerRight);

        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "发生错误: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
    private void saveHeaderSettings(String headerType, String headerLeft, String headerCenter, String headerRight) {
        try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + DB_NAME)) {
            // 构建列名和宽度比例字符串
            StringBuilder columnNames = new StringBuilder();
            StringBuilder widthRatios = new StringBuilder();

            // 遍历所有列名字段和宽度微调器
            for (int i = 0; i < columnFields.length; i++) {
                String text = columnFields[i].getText().trim();
                if (!text.isEmpty()) {
                    if (columnNames.length() > 0) {
                        columnNames.append(",");
                        widthRatios.append(",");
                    }
                    columnNames.append(text);
                    widthRatios.append(widthSpinners[i].getValue());
                }
            }

            String sql = "INSERT OR REPLACE INTO " + TABLE_NAME + " " +
                    "(header_type, column_names, width_ratios, header_left, header_center, header_right) " +
                    "VALUES (?, ?, ?, ?, ?, ?)";
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, headerType);
                pstmt.setString(2, columnNames.toString());
                pstmt.setString(3, widthRatios.toString());
                pstmt.setString(4, headerLeft);
                pstmt.setString(5, headerCenter);
                pstmt.setString(6, headerRight);
                pstmt.executeUpdate();
            }

            // 更新内存中的设置
            savedColumnSettings.put(headerType, columnNames.toString());
            savedWidthSettings.put(headerType, widthRatios.toString());
            savedHeaderLeftSettings.put(headerType, headerLeft);
            savedHeaderCenterSettings.put(headerType, headerCenter);
            savedHeaderRightSettings.put(headerType, headerRight);

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

    private String getCellValueAsString(Cell cell) {
        if (cell == null) return "";

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                } else {
                    double numValue = cell.getNumericCellValue();
                    if (numValue == Math.floor(numValue)) {
                        return String.valueOf((int) numValue);
                    } else {
                        return String.valueOf(numValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    return cell.getNumericCellValue() + "";
                }
            default:
                return "";
        }
    }

    private void showPreviewTable(DefaultTableModel tableModel, List<String> columns, List<Integer> widthRatios,
                                  String headerLeft, String headerCenter, String headerRight) {
        if (tableModel == null || columns == null || widthRatios == null) {
            JOptionPane.showMessageDialog(this, "表格数据错误", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        boolean fillBlankRows = fillBlankRowsCheckbox.isSelected();
        float rowHeightFactor = fillBlankRows ?
                Float.parseFloat((String) blankRowCombo.getSelectedItem()) : 1.0f;

        JDialog previewDialog = new JDialog(this, "打印预览", true);
        previewDialog.setSize(900, 700);
        previewDialog.setLocationRelativeTo(this);

        JPanel contentPanel = new JPanel(new BorderLayout());
        contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        String selectedFile = (String) excelFileCombo.getSelectedItem();
        String headerType = getSelectedHeaderType();
        String groupColumn = groupField != null ? groupField.getText().trim() : "";

        String titleText = String.format(
                "<html><div style='text-align:center; font-weight:bold; font-size:16px;'>" +
                        "鑫盾打印预览</div><br>" +
                        "<table><tr>" +
                        "<td><b>文件:</b></td><td>%s</td>" +
                        "<td style='width:50px'></td>" +
                        "<td><b>抬头类型:</b></td><td>%s</td>" +
                        "</tr><tr>" +
                        "<td><b>分组列:</b></td><td>%s</td>" +
                        "<td style='width:50px'></td>" +
                        "<td><b>显示列数:</b></td><td>%d</td>" +
                        "</tr><tr>" +
                        "<td><b>页眉左:</b></td><td>%s</td>" +
                        "<td style='width:50px'></td>" +
                        "<td><b>页眉中:</b></td><td>%s</td>" +
                        "<td style='width:50px'></td>" +
                        "<td><b>页眉右:</b></td><td>%s</td>" +
                        "</tr></table></html>",
                selectedFile != null ? selectedFile : "",
                headerType != null ? headerType : "未选择",
                groupColumn.isEmpty() ? "无" : groupColumn,
                columns.size(),
                headerLeft, headerCenter, headerRight
        );
        JLabel titleLabel = new JLabel(titleText);
        contentPanel.add(titleLabel, BorderLayout.NORTH);

        // 使用副本避免修改原始数据
        List<String> displayColumns = new ArrayList<>(columns);
        List<Integer> displayWidthRatios = new ArrayList<>(widthRatios);

        // 添加序号列（如果需要）
        boolean addSerialColumn = serialCheckbox.isSelected();
        if (addSerialColumn) {
            String serialColName = "卷内文件目录".equals(headerType) ? "件号" : "序号";
            displayColumns.add(0, serialColName);
            displayWidthRatios.add(0, 5);
        }

        // 创建带序号的表格模型
        DefaultTableModel displayModel;
        if (addSerialColumn) {
            String serialColName = "卷内文件目录".equals(headerType) ? "件号" : "序号";
            displayModel = new DefaultTableModel() {
                @Override
                public int getColumnCount() {
                    return tableModel.getColumnCount() + 1;
                }

                @Override
                public String getColumnName(int column) {
                    return column == 0 ? serialColName : tableModel.getColumnName(column - 1);
                }

                @Override
                public Object getValueAt(int row, int column) {
                    if (column == 0) return row + 1;
                    return tableModel.getValueAt(row, column - 1);
                }

                @Override
                public int getRowCount() {
                    return tableModel.getRowCount();
                }

                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
            };
        } else {
            displayModel = tableModel;
        }

        JTable dataTable = new JTable(displayModel);
        dataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        dataTable.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 12));
        dataTable.setRowHeight(25);

        int tableWidth = 800;
        if (dataTable.getParent() != null) {
            tableWidth = dataTable.getParent().getWidth() - 20;
        }

        // 设置列宽 - 使用安全的列数检查
        int columnCount = dataTable.getColumnCount();
        double totalRatio = displayWidthRatios.stream().mapToInt(Integer::intValue).sum();

        for (int i = 0; i < columnCount; i++) {
            if (i < displayWidthRatios.size()) {
                int colWidth = (int) ((tableWidth * displayWidthRatios.get(i)) / totalRatio);
                dataTable.getColumnModel().getColumn(i).setPreferredWidth(Math.max(colWidth, 50));
            }
        }

        JScrollPane scrollPane = new JScrollPane(dataTable);
        contentPanel.add(scrollPane, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel();
        JButton printBtn = new JButton("打印");
        JButton exportBtn = new JButton("导出Word");
        JButton exportPdfBtn = new JButton("导出PDF");
        JButton closeBtn = new JButton("关闭");

        exportPdfBtn.addActionListener(e -> {
            try {

                DefaultTableModel fullModel = createFullModelFromExcel(selectedFile);
                String currentHeaderType = getSelectedHeaderType();
                String groupCol = groupField.getText().trim();

                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileFilter(new FileNameExtensionFilter("PDF文件", "pdf"));
                if (fileChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
                    return; // 用户取消
                }

                File outputFile = fileChooser.getSelectedFile();
                if (!outputFile.getName().toLowerCase().endsWith(".pdf")) {
                    outputFile = new File(outputFile.getAbsolutePath() + ".pdf");
                }


                // 从数据库加载字体设置（格式：表头大小,表头粗体,正文大小,正文粗体,标题大小,标题粗体）
                Map<String, String> settings = savedSettingsMap.getOrDefault(currentHeaderType, new HashMap<>());
                String fontSettingStr = settings.getOrDefault("font_settings", "10,true,9,false,16,true");
                String[] fontSettings = fontSettingStr.split(",");
                String subtitleFontSetting = settings.getOrDefault("subtitle_font_settings", "9,false");
                String[] subtitleParts = subtitleFontSetting.split(",");
                int subtitleFontSize = 9;
                boolean subtitleBold = false;
                if (subtitleParts.length >= 2) {
                    subtitleFontSize = Integer.parseInt(subtitleParts[0]);
                    subtitleBold = Boolean.parseBoolean(subtitleParts[1]);
                }

                // 确保有足够的设置值
                int headerFontSize = fontSettings.length > 0 ? Integer.parseInt(fontSettings[0]) : 10;
                boolean headerBold = fontSettings.length > 1 ? Boolean.parseBoolean(fontSettings[1]) : true;
                int bodyFontSize = fontSettings.length > 2 ? Integer.parseInt(fontSettings[2]) : 9;
                boolean bodyBold = fontSettings.length > 3 ? Boolean.parseBoolean(fontSettings[3]) : false;
                int titleFontSize = fontSettings.length > 4 ? Integer.parseInt(fontSettings[4]) : 16;
                boolean titleBold = fontSettings.length > 5 ? Boolean.parseBoolean(fontSettings[5]) : true;

                //序号
                String serialColName = serialNameField.getText().trim();
                int serialWidth = (Integer) serialWidthSpinner.getValue();
                // 调用PDF导出方法（传递数据库中的字体设置）
                PDFExporter.exportToPDF(
                        fullModel,
                        columns,
                        widthRatios,
                        outputFile.getAbsolutePath(),
                        currentHeaderType,
                        headerLeft,
                        headerCenter,
                        headerRight,
                        groupCol,
                        addSerialColumn,
                        headerFontSize,
                        headerBold,
                        bodyFontSize,
                        bodyBold,
                        titleFontSize,
                        titleBold,
                        subtitleFontSize,
                        subtitleBold,
                        fillBlankRows,
                        rowHeightFactor,
                        serialColName,    // 序号列
                        serialWidth      // 序号列宽度
                );
                previewDialog.dispose();
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(previewDialog,
                        "导出PDF时出错: " + ex.getMessage(),
                        "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        closeBtn.addActionListener(e -> previewDialog.dispose());
        printBtn.addActionListener(e -> {
            JOptionPane.showMessageDialog(this, "打印功能待实现");
        });
        exportBtn.addActionListener(e -> {
            try {
                exportToWord(tableModel, columns, widthRatios, selectedFile, headerType);
                previewDialog.dispose();
            } catch (Exception ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(previewDialog,
                        "导出Word时出错: " + ex.getMessage(),
                        "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        buttonPanel.add(printBtn);
        buttonPanel.add(exportBtn);
        buttonPanel.add(closeBtn);
        buttonPanel.add(exportPdfBtn);
        contentPanel.add(buttonPanel, BorderLayout.SOUTH);

        previewDialog.add(contentPanel);
        previewDialog.setVisible(true);
    }
    private DefaultTableModel createFullModelFromExcel(String filePath) throws IOException {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            Workbook workbook = filePath.endsWith(".xlsx") ?
                    new XSSFWorkbook(fis) : new HSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0);

            // 获取所有列名
            List<String> allHeaders = new ArrayList<>();
            for (Cell cell : headerRow) {
                allHeaders.add(getCellValueAsString(cell));
            }

            // 创建完整模型
            DefaultTableModel fullModel = new DefaultTableModel();
            for (String header : allHeaders) {
                fullModel.addColumn(header);
            }

            // 添加所有数据行
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Vector<Object> dataRow = new Vector<>();
                for (int colIndex = 0; colIndex < allHeaders.size(); colIndex++) {
                    Cell cell = row.getCell(colIndex);
                    dataRow.add(cell != null ? getCellValueAsString(cell) : "");
                }
                fullModel.addRow(dataRow);
            }

            return fullModel;
        }
    }
//    private void exportToPDF(DefaultTableModel model, List<String> columns, List<Integer> widthRatios,
//                             String filePath, String headerType,
//                             String headerLeft, String headerCenter, String headerRight,
//                             String groupColumn, boolean addSerialColumn,
//                             int headerFontSize, boolean headerBold,
//                             int bodyFontSize, boolean bodyBold,
//                             int titleFontSize, boolean titleBold) { // 新增标题字体参数
//
//        // 1. 获取分组列名
//        String groupCol = groupField.getText().trim();
//        Map<String, String> settings = savedSettingsMap.getOrDefault(headerType, new HashMap<>());
//        String subtitleFontSetting = settings.getOrDefault("subtitle_font_settings", "9,false");
//        String[] subtitleParts = subtitleFontSetting.split(",");
//        int subtitleFontSize = 9;
//        boolean subtitleBold = false;
//        if (subtitleParts.length >= 2) {
//            subtitleFontSize = Integer.parseInt(subtitleParts[0]);
//            subtitleBold = Boolean.parseBoolean(subtitleParts[1]);
//        }
//        // 2. 选择保存位置
//        JFileChooser fileChooser = new JFileChooser();
//        fileChooser.setFileFilter(new FileNameExtensionFilter("PDF文件", "pdf"));
//        if (fileChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
//            return; // 用户取消
//        }
//
//        File outputFile = fileChooser.getSelectedFile();
//        if (!outputFile.getName().toLowerCase().endsWith(".pdf")) {
//            outputFile = new File(outputFile.getAbsolutePath() + ".pdf");
//        }
//
//        // 3. 调用PDF导出器（传递所有16个参数）
//        PDFExporter.exportToPDF(
//                model,
//                columns,
//                widthRatios,
//                outputFile.getAbsolutePath(),
//                headerType,
//                headerLeft,
//                headerCenter,
//                headerRight,
//                groupCol,
//                addSerialColumn,
//                headerFontSize,
//                headerBold,
//                bodyFontSize,
//                bodyBold,
//                titleFontSize, // 新增标题字体大小
//                titleBold,
//                subtitleFontSize, subtitleBold// 新增标题是否加粗
//        );
//    }

    private void setupPageProperties(XWPFDocument doc, String headerType) {
        CTDocument1 document = doc.getDocument();
        CTBody body = document.getBody();
        if (!body.isSetSectPr()) {
            body.addNewSectPr();
        }
        CTSectPr sectPr = body.getSectPr();
        if (!sectPr.isSetPgSz()) {
            sectPr.addNewPgSz();
        }
        CTPageSz pageSize = sectPr.getPgSz();
        pageSize.setW(BigInteger.valueOf(12240));
        pageSize.setH(BigInteger.valueOf(15840));
        pageSize.setOrient(STPageOrientation.PORTRAIT);

        // 设置页边距（上、下、左、右）
        if (!sectPr.isSetPgMar()) {
            sectPr.addNewPgMar();
        }
        CTPageMar pageMar = sectPr.getPgMar();

        // 根据抬头类型设置不同的页边距
        if ("盒内文件目录".equals(headerType)) {
            // 0.4英寸 = 576缇
            pageMar.setTop(BigInteger.valueOf(576));    // 上边距
            pageMar.setBottom(BigInteger.valueOf(576)); // 下边距
            pageMar.setLeft(BigInteger.valueOf(576));   // 左边距
            pageMar.setRight(BigInteger.valueOf(576));  // 右边距
        } else {
            // 默认页边距（卷内文件目录）
            pageMar.setTop(BigInteger.valueOf(864));    // 上边距
            pageMar.setBottom(BigInteger.valueOf(864)); // 下边距
            pageMar.setLeft(BigInteger.valueOf(1440));  // 左边距
            pageMar.setRight(BigInteger.valueOf(952));  // 右边距
        }
    }

    private void setupTableBorder(XWPFTable table) {
        CTTblPr tblPr = table.getCTTbl().addNewTblPr();
        if (tblPr == null) {
            tblPr = table.getCTTbl().addNewTblPr();
        }

        CTTblBorders borders;
        if (tblPr.isSetTblBorders()) {
            borders = tblPr.getTblBorders();
        } else {
            borders = tblPr.addNewTblBorders();
        }

        if (borders.isSetTop()) borders.unsetTop();
        if (borders.isSetBottom()) borders.unsetBottom();
        if (borders.isSetLeft()) borders.unsetLeft();
        if (borders.isSetRight()) borders.unsetRight();
        if (borders.isSetInsideH()) borders.unsetInsideH();
        if (borders.isSetInsideV()) borders.unsetInsideV();

        setBorder(borders.addNewTop(), STBorder.SINGLE, 4);
        setBorder(borders.addNewBottom(), STBorder.SINGLE, 4);
        setBorder(borders.addNewLeft(), STBorder.SINGLE, 4);
        setBorder(borders.addNewRight(), STBorder.SINGLE, 4);
        setBorder(borders.addNewInsideH(), STBorder.SINGLE, 4);
        setBorder(borders.addNewInsideV(), STBorder.SINGLE, 4);

        tblPr.addNewTblLayout().setType(STTblLayoutType.FIXED);
    }

    private void setBorder(CTBorder border, STBorder.Enum style, int size) {
        border.setVal(style);
        border.setSz(BigInteger.valueOf(size));
    }

    private void setCellBorders(CTTcBorders borders) {
        setBorder(borders.addNewBottom(), STBorder.SINGLE, 4);
        setBorder(borders.addNewTop(), STBorder.SINGLE, 4);
        setBorder(borders.addNewLeft(), STBorder.SINGLE, 4);
        setBorder(borders.addNewRight(), STBorder.SINGLE, 4);
    }

    private void setTableCellPadding(XWPFTable table, int top, int left, int bottom, int right) {
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        if (tblPr == null) {
            tblPr = table.getCTTbl().addNewTblPr();
        }

        CTTblCellMar cellMar;
        if (tblPr.isSetTblCellMar()) {
            cellMar = tblPr.getTblCellMar();
        } else {
            cellMar = tblPr.addNewTblCellMar();
        }

        CTTblWidth topMargin = cellMar.addNewTop();
        topMargin.setW(BigInteger.valueOf(top));
        topMargin.setType(STTblWidth.DXA);

        CTTblWidth leftMargin = cellMar.addNewLeft();
        leftMargin.setW(BigInteger.valueOf(left));
        leftMargin.setType(STTblWidth.DXA);

        CTTblWidth bottomMargin = cellMar.addNewBottom();
        bottomMargin.setW(BigInteger.valueOf(bottom));
        bottomMargin.setType(STTblWidth.DXA);

        CTTblWidth rightMargin = cellMar.addNewRight();
        rightMargin.setW(BigInteger.valueOf(right));
        rightMargin.setType(STTblWidth.DXA);
    }



    private void addBlankRowsIfNeeded(XWPFTable table, int columnsCount) {
        int currentRows = table.getNumberOfRows();
        int desiredRowsPerPage = 25;
        int blankRowsNeeded = desiredRowsPerPage - (currentRows % desiredRowsPerPage);

        if (blankRowsNeeded > 0 && blankRowsNeeded < desiredRowsPerPage) {
            for (int i = 0; i < blankRowsNeeded; i++) {
                XWPFTableRow row = table.createRow();
                for (int j = 0; j < columnsCount; j++) {
                    XWPFTableCell cell = row.getCell(j);
                    CTTc cttc = cell.getCTTc();
                    CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
                    tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                    setCellBorders(tcPr.addNewTcBorders());

                    if (cell.getParagraphs().isEmpty()) {
                        XWPFParagraph para = cell.addParagraph();
                        para.setAlignment(ParagraphAlignment.CENTER);
                        XWPFRun run = para.createRun();
                        run.setFontSize(10);
                        run.setFontFamily("宋体");
                        run.setText("");
                    }
                }
            }
        }
    }




    private void loadSettingsToFields(JTextField[] fields, JSpinner[] spinners, String headerType) {
        // 确保加载对应抬头类型的设置
        if (savedSettingsMap.containsKey(headerType)) {
            Map<String, String> settings = savedSettingsMap.get(headerType);
            String columnNames = settings.get("column_names");
            String widthRatios = settings.get("width_ratios");

            String[] names = columnNames != null ? columnNames.split(",") : new String[0];
            String[] ratios = widthRatios != null ? widthRatios.split(",") : new String[0];

            for (int i = 0; i < fields.length; i++) {
                if (i < names.length) {
                    fields[i].setText(names[i].trim());
                } else {
                    fields[i].setText("");
                }

                if (i < ratios.length && !ratios[i].isEmpty()) {
                    try {
                        spinners[i].setValue(Integer.parseInt(ratios[i]));
                    } catch (NumberFormatException e) {
                        spinners[i].setValue(0);
                    }
                } else {
                    spinners[i].setValue(0);
                }
            }
        } else {
            // 如果该类型没有保存过设置，清空字段
            for (JTextField field : fields) {
                field.setText("");
            }
            for (JSpinner spinner : spinners) {
                spinner.setValue(0);
            }
        }
    }

    private void saveColumnSettings(String headerType, String columnNames, String widthRatios,
                                    String headerLeft, String headerCenter, String headerRight,
                                    String fontSettings, String subtitleFontSettings) {
        try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + DB_NAME)) {
            String serialName = serialNameField.getText().trim();
            int serialWidth = (Integer) serialWidthSpinner.getValue();

            String sql = "INSERT OR REPLACE INTO " + TABLE_NAME + " " +
                    "(header_type, column_names, width_ratios, " +
                    "header_left, header_center, header_right, " +
                    "font_settings, subtitle_font_settings) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, headerType);
                pstmt.setString(2, columnNames);
                pstmt.setString(3, widthRatios);
                pstmt.setString(4, headerLeft);
                pstmt.setString(5, headerCenter);
                pstmt.setString(6, headerRight);
                pstmt.setString(7, fontSettings);
                pstmt.setString(8, subtitleFontSettings);
                pstmt.executeUpdate();
            }

            // 更新内存中的设置 - 确保独立存储
            Map<String, String> typeSettings = savedSettingsMap.computeIfAbsent(headerType, k -> new HashMap<>());
            typeSettings.put("column_names", columnNames);
            typeSettings.put("width_ratios", widthRatios);
            typeSettings.put("header_left", headerLeft);
            typeSettings.put("header_center", headerCenter);
            typeSettings.put("header_right", headerRight);
            typeSettings.put("font_settings", fontSettings);
            typeSettings.put("subtitle_font_settings", subtitleFontSettings);

            savedSettingsMap.put(headerType, typeSettings);

        } catch (SQLException ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(),
                    "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
}